Skip to content

Declare content signals, and advertise llms.txt in a Link header - #83

Merged
robbyrob42 merged 2 commits into
primaryfrom
rob/agent-readiness-signals
Sep 5, 2026
Merged

Declare content signals, and advertise llms.txt in a Link header#83
robbyrob42 merged 2 commits into
primaryfrom
rob/agent-readiness-signals

Conversation

@robbyrob42

Copy link
Copy Markdown
Collaborator

The two actionable gaps from the Cloudflare Radar agent-readiness scan (0f61525a), which put the property at Level 1 — Basic Web Presence, score 19: Bot Access Control 1/2, Discoverability 2/4.

Content Signals

robots.txt now declares:

Content-Signal: search=yes, ai-input=yes, ai-train=yes
Signal Means
search=yes index this, link to it in ordinary search results
ai-input=yes retrieve this to ground an AI answer, and cite it
ai-train=yes use this to train a model

All three yes, as a decision rather than a default. The property exists to be found by counsel who increasingly ask an assistant before they ask a colleague, and each permission is a way these words reach that reader. Withholding training consent while asking to be cited would be taking one side of the same bargain.

The repetition across all fourteen groups is load-bearing. Same rule as the named crawler blocks from #82: a named group replaces the wildcard rather than adding to it. A Content-Signal written only under User-agent: * would be invisible to GPTBot, ClaudeBot, PerplexityBot and every other crawler named beneath it — exactly the audience it addresses. Half-doing this would have been worse than skipping it: the file would read as a declaration while making none to anyone who matters.

Link header

New public/_headers:

Link: </llms.txt>; rel="describedby"; type="text/plain"

describedby is the IANA-registered relation for "the target describes this resource," which is what /llms.txt is — the property's own map of itself. An agent reading response headers finds it without parsing HTML or guessing at well-known paths.

Applied to /* rather than enumerated per route: an enumerated list silently misses the next route someone adds, and the cost of the broader match is one short header on asset responses nobody reads.

The Cloudflare adapter prepends its own /_astro/* immutable-cache rule to this file at build time, so both rules survive — verified in dist/client/_headers rather than assumed.

Not addressed, deliberately

Radar's Protocol Discovery is 0/9: API catalog, OAuth/OIDC discovery, OAuth protected resource, auth.md, MCP server card, A2A agent card, agent skills index, WebMCP, ARD manifest.

Every one of those describes an API or an agent that a site exposes. This is a brochure site for an expert-witness practice and exposes neither. Publishing an MCP server card for a site with no MCP server is a fabrication, and the same reasoning that keeps areaServed out of the schema applies. 0/9 is the correct score here, and chasing it would mean lying to a scanner.

Markdown content negotiation — the one genuinely useful item in the remaining set — is filed separately for the roadmap rather than bundled here.

Verification

yarn build clean; built robots.txt carries 14 User-agent: groups and 14 Content-Signal: lines. Built _headers contains both the adapter's rule and ours.

The Link header itself cannot be verified until this deploys — _headers is applied by Cloudflare at the edge, not by the build.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CpEXBMByKmpV1f9G7UUZhF

… Link header

Two gaps from the 2026-09-04 Cloudflare Radar agent-readiness scan, which put
the property at Level 1 with Bot Access Control at 1/2 and Discoverability at
2/4.

CONTENT SIGNALS. robots.txt now declares search=yes, ai-input=yes,
ai-train=yes. All three are a decision rather than a default. This property
exists to be found by counsel who increasingly ask an assistant before they ask
a colleague, and each permission is a way these words reach that reader.
Withholding training consent while asking to be cited would be taking one side
of the same bargain.

The declaration is repeated in all fourteen user-agent groups, and that
repetition is load-bearing for the same reason the named crawler blocks are: a
named group replaces the wildcard rather than adding to it. A Content-Signal
written only under `User-agent: *` would be invisible to GPTBot, ClaudeBot,
PerplexityBot and every other crawler named below it -- precisely the audience
it addresses. Getting this half-right would have been worse than not doing it,
because the file would have read as a declaration while making none.

LINK HEADER. A new public/_headers advertises /llms.txt with RFC 8288
`rel="describedby"`, the registered relation for "the target describes this
resource". An agent reading response headers finds the map without parsing HTML
or guessing at a well-known path.

Applied to /* rather than enumerated per route: an enumerated list silently
misses the next route added, and the cost of the broader match is one short
header on asset responses nobody reads. The Cloudflare adapter prepends its own
/_astro/* cache rule to this file at build time, so both rules survive --
verified in dist/client/_headers.

Not addressed, deliberately. Radar's Protocol Discovery is 0/9 -- API catalog,
OAuth/OIDC, MCP server card, A2A agent card, agent skills, WebMCP, ARD. Every
one of those describes an API or an agent that a site exposes. This is a
brochure site for an expert-witness practice and exposes neither, so publishing
any of them would be a fabrication. 0/9 is the correct score.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpEXBMByKmpV1f9G7UUZhF
The file was last touched 2026-08-08 and had drifted past usefulness: its
status table still recorded that forensics.rootsystem.com does not resolve,
which stopped being true when the route and DNS record landed on 2026-09-03.
Everything else in it is either done or superseded.

A stale roadmap is worse than no roadmap for the same reason a hand-kept
dateModified is worse than none: it is a claim nobody verifies, and it is
believed until someone acts on it.

Planning now lives in Linear.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CpEXBMByKmpV1f9G7UUZhF
@robbyrob42
robbyrob42 merged commit 3d7f8ef into primary Sep 5, 2026
4 checks passed
@robbyrob42
robbyrob42 deleted the rob/agent-readiness-signals branch September 5, 2026 02:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant